# -*- coding: utf-8 -*-
from django.db import models
from django.contrib.auth.models import User
from django.core.validators import MinValueValidator
from django.db.models.aggregates import Sum


#TipoMovimiento = (
#    ('1', 'Factura de Compra'),
#    ('2', 'Orden de Compra'),
#    ('3', 'Reintegro'),
#    ('4', 'Factura de Venta'),
#    ('5', 'Obsequio'),
#    ('6', 'Préstamo'),
#    ('7', 'Devolución'),
#)
TipoMovimiento = (
    ('1', 'ENTRADA'),
    ('2', 'SALIDA'),
    ('3', 'TRASLADO'),
)

class MovimientoTipo(models.Model):
    nombre = models.CharField(max_length=80, blank=True, null=True)
    observaciones = models.TextField(blank=True, null=True)
    tipo = models.CharField(max_length=1, choices=TipoMovimiento, blank=True, default='1')
    
    def __unicode__(self):
        return u"%s" %(self.producto)
    
    class Meta:
        verbose_name_plural = 'Tipos de movimientos'


def eliminarMovimiento(config_id, id_dcto):
    movimiento = Movimientos.objects.filter(configuracion_id=config_id, id_documento=id_dcto)
    movimiento.delete()
            
def actualizarInventario(config_id, cantidad, item_id, activo=True, sede_id=1):
    total_compras = 0
    total_ventas = 0
    total_salidas = 0
    total_entradas = 0
    inventario = Inventario.objects.filter(configuracion_id=config_id, item_id=item_id, sede_id=sede_id)
    if len(inventario)>0:
        inventario = Inventario.objects.get(configuracion_id=config_id, item_id=item_id, sede_id=sede_id)
        
        f_compras = FacturaCompra.objects.filter(configuracion_id=config_id, sede_id=sede_id)
        compras = FacturaCompraItem.objects.filter(factura_compra__in=f_compras, id=item_id).aggregate(cantidad=Sum('cantidad'))
        if compras['cantidad']!=None:
            total_compras = compras['cantidad']
        else:
            total_compras = 0
        
        f_ventas = FacturaVenta.objects.filter(configuracion_id=config_id, sede_id=sede_id)
        ventas = FacturaVentaItem.objects.filter(factura_venta__in=f_ventas, producto_id=item_id).aggregate(cantidad=Sum('cantidad'))
        if ventas['cantidad']!=None:
            total_ventas = ventas['cantidad']
        else:
            total_ventas = 0
        
        traslados = Traslado.objects.filter(configuracion_id=config_id, sede_origen=sede_id, producto_id=item_id).aggregate(cantidad=Sum('cantidad'))
        if traslados['cantidad']!=None:
            total_salidas = traslados['cantidad']
        else:
            total_salidas = 0
            
        traslados = Traslado.objects.filter(configuracion_id=config_id, sede_destino=sede_id, producto_id=item_id).aggregate(cantidad=Sum('cantidad'))
        if traslados['cantidad']!=None:
            total_entradas = traslados['cantidad']
        else:
            total_entradas = 0
        
        cantidad = total_compras + total_entradas - total_ventas - total_salidas
        if cantidad > 0:
            inventario.cantidad = total_compras + total_entradas - total_ventas - total_salidas 
            inventario.activo = activo
            inventario.save()
        else:
            inventario.delete()
    else:
        inventario = Inventario(configuracion_id=config_id, item_id=item_id, cantidad=cantidad, sede_id=sede_id, activo=False)
        inventario.save()
    
class Configuracion(models.Model):
    nit = models.CharField(max_length=20, blank=True, null=True)
    nombre = models.CharField(max_length = 250, blank=True, null=True)
    direccion = models.CharField(max_length = 80, blank=True, null=True)
    telefono = models.CharField(max_length = 20, blank=True, null=True)
    fax = models.CharField(max_length = 20, blank=True, null=True)
    email = models.CharField(max_length = 80, blank=True, null=True)
    web = models.CharField(max_length = 80, blank=True, null=True)
    logo = models.ImageField(upload_to='img', blank=True)
    renovacion_hosting = models.DateField(verbose_name='Fecha de renovacion de Hosting', help_text='Indica la fecha en que debe renovarse el hosting.', blank=True, null=True)
    version_producto = models.CharField(max_length = 20, blank=True, null=True)
    observaciones = models.TextField(blank=True, null=True)
    
    def __unicode__(self):
        return u"%s" %(self.nombre)
    
    class Meta:
        verbose_name_plural = 'Configuraciones'


class Notificaciones(models.Model):
    configuracion = models.ForeignKey(Configuracion)
    correo = models.TextField(blank=True, null=True, help_text='Correos electrónicos separados por coma.')
    
    def __unicode__(self):
        return u"%s" %("Notificaciones")

    
class Sede(models.Model):
    configuracion = models.ForeignKey(Configuracion)
    nombre = models.CharField(max_length = 250)
    abrev = models.CharField(max_length = 20, blank=True, null=True)
    direccion = models.CharField(max_length = 80, blank=True, null=True)
    telefono = models.CharField(max_length = 20, blank=True, null=True)
    fax = models.CharField(max_length = 20, blank=True, null=True)
    email = models.CharField(max_length = 80, blank=True, null=True)
    
    def __unicode__(self):
        return u"%s" %(self.nombre)


class ConfiguracionUsuario(models.Model):
    configuracion = models.ForeignKey(Configuracion)
    usuario = models.ForeignKey(User, verbose_name='Usuario', blank=True)
    identificacion = models.CharField(max_length=20, blank=True, null=True)
    telefono = models.CharField(max_length = 20, blank=True, null=True)
    
    def __unicode__(self):
        return u"%s - %s" %(self.configuracion, self.usuario)
    
    class Meta:
        verbose_name_plural = 'Configuraciones de usuario'
        

class ConfiguracionUsuarioSede(models.Model):
    configuracion_usuario = models.ForeignKey(ConfiguracionUsuario)
    sede = models.ForeignKey(Sede)
    
    def __unicode__(self):
        return u"%s - %s" %(self.configuracion_usuario, self.sede)
    
    class Meta:
        verbose_name_plural = 'Usuarios en sede'


class Proveedor (models.Model):
    configuracion = models.ForeignKey(Configuracion)
    nit = models.CharField(max_length=20, blank=True, null=True)
    nombre = models.CharField(max_length = 250, blank=True, null=True)
    direccion = models.CharField(max_length = 80, blank=True, null=True)
    telefono = models.CharField(max_length = 20, blank=True, null=True)
    fax = models.CharField(max_length = 20, blank=True, null=True)
    email = models.CharField(max_length = 80, blank=True, null=True)
    web = models.CharField(max_length = 80, blank=True, null=True)
    logo = models.ImageField(upload_to='img', blank=True)
    observaciones = models.TextField(blank=True, null=True)
    laboratorio = models.BooleanField(blank=True, default=0)
     
    def __unicode__(self):
        return u"%s" %(self.nombre)
    
    class Meta:
        verbose_name_plural = 'Proveedores'


class Categoria (models.Model):
    configuracion = models.ForeignKey(Configuracion)
    nombre = models.CharField(max_length = 250)
    abrev = models.CharField(max_length = 20, blank=True, null=True)
    sismed = models.BooleanField(blank=True, default=0)
    dias_vencimiento = models.IntegerField(validators=[MinValueValidator(0)], default=0, blank=True, null=True)
    
    def __unicode__(self):
        return self.nombre
    
    class Meta:
        verbose_name_plural = 'Categorías'


class Iva (models.Model):
    configuracion = models.ForeignKey(Configuracion)
    nombre = models.CharField(max_length = 250)
    valor = models.FloatField(validators=[MinValueValidator(0)], blank=True, null=True, default=0)
    
    def __unicode__(self):
        return self.nombre
    
    class Meta:
        verbose_name_plural = 'Iva'


class Unidad (models.Model):
    configuracion = models.ForeignKey(Configuracion)
    nombre = models.CharField(max_length = 250)
    abrev = models.CharField(max_length = 20, blank=True, null=True)
    
    def __unicode__(self):
        return self.abrev
    
    class Meta:
        verbose_name_plural = 'Unidades'


class Producto (models.Model):
    configuracion = models.ForeignKey(Configuracion)
    nombre = models.CharField(max_length = 250)
    laboratorio = models.ForeignKey(Proveedor)
    descripcion = models.TextField(blank=True, null=True)
    categoria = models.ForeignKey(Categoria, blank=True, null=True)
    unidad = models.ForeignKey(Unidad, blank=True, null=True)
    cum = models.CharField(max_length=20, blank=True, null=True)
    invima = models.CharField(max_length=100, blank=True, null=True)
    codigo = models.CharField(max_length=50, blank=True, null=True)
    logo = models.ImageField(upload_to='img', blank=True)
    observaciones = models.TextField(blank=True, null=True)
    
    def __unicode__(self):
        return u"%s" %(self.nombre)


class FacturaCompra(models.Model):
    configuracion = models.ForeignKey(Configuracion)
    movimiento_tipo = models.ForeignKey(MovimientoTipo, default=1)
    proveedor = models.ForeignKey(Proveedor, blank=True, null=True, default="")
    sede = models.ForeignKey(Sede)
    numero = models.BigIntegerField(validators=[MinValueValidator(0)])
    fecha_emision = models.DateField(verbose_name='Fecha de emisión', help_text='Indica la fecha en que fué emitida la factura.', blank=True, null=True)
    fecha_vencimiento = models.DateField(verbose_name='Fecha de vencimiento', help_text='Indica la fecha de vencimiento de factura.', blank=True, null=True)
    vendedor = models.CharField(max_length=80, blank=True, null=True)
    orden_compra = models.CharField(max_length=20, blank=True, null=True)
    subtotal = models.FloatField(validators=[MinValueValidator(0)], blank=True, null=True, default=0)
    iva = models.FloatField(validators=[MinValueValidator(0)], blank=True, null=True, default=0)
    ajuste_peso = models.FloatField(blank=True, null=True, default=0)
    retefuente = models.FloatField(blank=True, null=True, default=0)
    reteiva = models.FloatField(blank=True, null=True, default=0)
    transporte = models.FloatField(blank=True, null=True, default=0)
    descuento = models.FloatField(blank=True, null=True, default=0)
    reteica = models.FloatField(blank=True, null=True, default=0)
    retecre = models.FloatField(blank=True, null=True, default=0)
    cuatroxmil = models.FloatField(blank=True, null=True, default=0)
    total = models.FloatField(validators=[MinValueValidator(0)], blank=True, null=True, default=0)
    pagada = models.BooleanField(blank=True, default=0)
    observaciones = models.TextField(blank=True, null=True)
    
    def delete(self, *args, **kwargs):
        eliminarMovimiento(self.configuracion.id, self.id)
        super(FacturaCompra, self).delete(*args, **kwargs)
        
    def __unicode__(self):
        return u"%s" %(self.numero)
    
    class Meta:
        verbose_name_plural = 'Facturas de compra'


class FacturaCompraItem(models.Model):
    configuracion = models.ForeignKey(Configuracion)
    factura_compra = models.ForeignKey(FacturaCompra)
    producto = models.ForeignKey(Producto)
    cantidad = models.IntegerField(validators=[MinValueValidator(0)], default=0, blank=True, null=True)
    lote = models.CharField(max_length=80, verbose_name='Lote', help_text='Lote.', blank=True, null=True)
    fecha_vencimiento = models.DateField(verbose_name='Fecha de vencimiento', help_text='Indica la fecha de vencimiento del producto.', blank=True, null=True)
    valor_unitario = models.FloatField(validators=[MinValueValidator(0)], blank=True, null=True, default=0)
    iva = models.FloatField(validators=[MinValueValidator(0)], blank=True, null=True, default=0)
    valor_venta = models.FloatField(validators=[MinValueValidator(0)], blank=True, null=True, default=0)
    
    def save(self, *args, **kwargs):
        super(FacturaCompraItem, self).save(*args, **kwargs)
        actualizarInventario(self.configuracion.id, self.cantidad, self.id, True, self.factura_compra.sede_id)
    
    def delete(self, *args, **kwargs):
        actualizarInventario(self.configuracion.id, self.cantidad, self.id, False, self.factura_compra.sede_id)
        super(FacturaCompraItem, self).delete(*args, **kwargs)
        
    def __unicode__(self):
        return u"%s" %(self.producto.nombre)
    
    class Meta:
        verbose_name_plural = 'Items Facturas de Compra'


class Inventario(models.Model):
    configuracion = models.ForeignKey(Configuracion)
    item = models.ForeignKey(FacturaCompraItem)
    cantidad = models.IntegerField(validators=[MinValueValidator(0)], default=0, blank=True, null=True)
    sede = models.ForeignKey(Sede, default=1, blank=True, null=True)
    activo = models.BooleanField(blank=True, default=0)
    
    def __unicode__(self):
        return u"%s" %(self.item)
    
    class Meta:
        unique_together = ("configuracion", "item", "sede")
        verbose_name_plural = 'Artículos en inventario'
        
    

class FacturaVenta(models.Model):
    configuracion = models.ForeignKey(Configuracion)
    movimiento_tipo = models.ForeignKey(MovimientoTipo, default=11)
    cliente = models.CharField(max_length=80, blank=True, null=True)
    sede = models.ForeignKey(Sede)
    numero = models.BigIntegerField(validators=[MinValueValidator(0)])
    fecha_emision = models.DateField(verbose_name='Fecha de emisión', help_text='Indica la fecha en que fué emitida la factura.', blank=True, null=True)
    fecha_vencimiento = models.DateField(verbose_name='Fecha de vencimiento', help_text='Indica la fecha de vencimiento de factura.', blank=True, null=True)
    vendedor = models.CharField(max_length=80, blank=True, null=True)
    orden_venta = models.CharField(max_length=20, blank=True, null=True)
    subtotal = models.FloatField(validators=[MinValueValidator(0)], blank=True, null=True, default=0)
    iva = models.FloatField(validators=[MinValueValidator(0)], blank=True, null=True, default=0)
    ajuste_peso = models.FloatField(validators=[MinValueValidator(0)], blank=True, null=True, default=0)
    retefuente = models.FloatField(validators=[MinValueValidator(0)], blank=True, null=True, default=0)
    reteiva = models.FloatField(validators=[MinValueValidator(0)], blank=True, null=True, default=0)
    transporte = models.FloatField(validators=[MinValueValidator(0)], blank=True, null=True, default=0)
    total = models.FloatField(validators=[MinValueValidator(0)], blank=True, null=True, default=0)
    pagada = models.BooleanField(blank=True, default=0)
    observaciones = models.TextField(blank=True, null=True)
    
    def __unicode__(self):
        return u"%s" %(self.numero)
    
    class Meta:
        verbose_name_plural = 'Facturas de compra'


class FacturaVentaItem(models.Model):
    configuracion = models.ForeignKey(Configuracion)
    factura_venta = models.ForeignKey(FacturaVenta)
    producto = models.ForeignKey(FacturaCompraItem)
    cantidad = models.IntegerField(validators=[MinValueValidator(0)], default=0, blank=True, null=True)
    fecha_vencimiento = models.DateField(verbose_name='Fecha de vencimiento', help_text='Indica la fecha de vencimiento del producto.', blank=True, null=True)
    valor_unitario = models.FloatField(validators=[MinValueValidator(0)], blank=True, null=True, default=0)
    iva = models.FloatField(validators=[MinValueValidator(0)], blank=True, null=True, default=0)
 
    def save(self, *args, **kwargs):
        super(FacturaVentaItem, self).save(*args, **kwargs)
        actualizarInventario(self.configuracion.id, self.cantidad, self.producto.id, True, self.factura_venta.sede_id)
    
    def delete(self, *args, **kwargs):
        super(FacturaVentaItem, self).delete(*args, **kwargs)
        actualizarInventario(self.configuracion.id, self.cantidad, self.producto.id, False, self.factura_venta.sede_id)
        
    def __unicode__(self):
        return u"%s" %(self.producto.nombre)
    
    class Meta:
        verbose_name_plural = 'Items Facturas de Venta'
    

class Movimientos(models.Model):
    configuracion = models.ForeignKey(Configuracion)
    tipo_movimiento = models.ForeignKey(MovimientoTipo)
    fecha = models.DateField(verbose_name='Fecha de movimiento', help_text='Indica la fecha de movimiento del producto.', blank=True, null=True)
    responsable = models.ForeignKey(User)
    id_documento = models.IntegerField(validators=[MinValueValidator(0)], default=0, blank=True, null=True)
    observaciones = models.TextField(blank=True, null=True)
    
    def __unicode__(self):
        return u"%s" %(self.producto)
    
    class Meta:
        unique_together = ("configuracion", "tipo_movimiento", "id_documento")
        verbose_name_plural = 'Movimientos de productos'


class Traslado(models.Model):
    configuracion = models.ForeignKey(Configuracion)
    fecha = models.DateField(verbose_name='Fecha de traslado', help_text='Indica la fecha de movimiento del producto.', blank=True, null=True)
    sede_origen = models.ForeignKey(Sede, related_name='sede_origen')
    sede_destino = models.ForeignKey(Sede, related_name='sede_destino')
    producto = models.ForeignKey(FacturaCompraItem)
    cantidad = models.IntegerField(validators=[MinValueValidator(0)], default=0, blank=True, null=True)
    responsable = models.ForeignKey(User)
    
    def save(self, *args, **kwargs):
        super(Traslado, self).save(*args, **kwargs)
        actualizarInventario(self.configuracion.id, self.cantidad, self.producto.id, True, self.sede_origen.id)
        actualizarInventario(self.configuracion.id, self.cantidad, self.producto.id, True, self.sede_destino.id)
    
    def delete(self, *args, **kwargs):
        super(Traslado, self).delete(*args, **kwargs)
        actualizarInventario(self.configuracion.id, self.cantidad, self.producto.id, True, self.sede_origen.id)
        actualizarInventario(self.configuracion.id, self.cantidad, self.producto.id, True, self.sede_destino.id)
            
    def __unicode__(self):
        return u"%s" %(self.fecha)
    
class OrdenFactura(models.Model):
    configuracion = models.ForeignKey(Configuracion)
    movimiento_tipo = models.ForeignKey(MovimientoTipo, default=1)
    proveedor = models.ForeignKey(Proveedor, blank=True, null=True, default="")
    sede = models.ForeignKey(Sede)
    numero = models.BigIntegerField(validators=[MinValueValidator(0)])
    fecha_emision = models.DateField(verbose_name='Fecha de emisión', help_text='Indica la fecha en que fué emitida la factura.', blank=True, null=True)
    fecha_vencimiento = models.DateField(verbose_name='Fecha de vencimiento', help_text='Indica la fecha de vencimiento de factura.', blank=True, null=True)
    vendedor = models.CharField(max_length=80, blank=True, null=True)
    orden_compra = models.ForeignKey(FacturaCompra, default=1)
    orden_numero = models.CharField(max_length=20, blank=True, null=True)
    subtotal = models.FloatField(validators=[MinValueValidator(0)], blank=True, null=True, default=0)
    iva = models.FloatField(validators=[MinValueValidator(0)], blank=True, null=True, default=0)
    ajuste_peso = models.FloatField(blank=True, null=True, default=0)
    retefuente = models.FloatField(blank=True, null=True, default=0)
    reteiva = models.FloatField(blank=True, null=True, default=0)
    transporte = models.FloatField(blank=True, null=True, default=0)
    descuento = models.FloatField(blank=True, null=True, default=0)
    reteica = models.FloatField(blank=True, null=True, default=0)
    retecre = models.FloatField(blank=True, null=True, default=0)
    cuatroxmil = models.FloatField(blank=True, null=True, default=0)
    total = models.FloatField(validators=[MinValueValidator(0)], blank=True, null=True, default=0)
    pagada = models.BooleanField(blank=True, default=0)
    observaciones = models.TextField(blank=True, null=True)
    
    def delete(self, *args, **kwargs):
        eliminarMovimiento(self.configuracion.id, self.id)
        super(FacturaCompra, self).delete(*args, **kwargs)
        
    def __unicode__(self):
        return u"%s" %(self.numero)
    
    class Meta:
        verbose_name_plural = 'Convertir Orden de entrada en Factura de compra'


class OrdenFacturaItem(models.Model):
    configuracion = models.ForeignKey(Configuracion)
    orden_factura = models.ForeignKey(OrdenFactura)
    item = models.ForeignKey(FacturaCompraItem)
    cantidad = models.IntegerField(validators=[MinValueValidator(0)], default=0, blank=True, null=True) 
    
    def __unicode__(self):
        self.producto.nombre
    class Meta:
        verbose_name_plural = 'Convertir Orden de entrada en Factura de compra'
        
        
class Reintegro(models.Model):
    configuracion = models.ForeignKey(Configuracion)
    fecha = models.DateField(verbose_name='Fecha de traslado', help_text='Indica la fecha de reintegro.', blank=True, null=True)
    factura_compra = models.ForeignKey(FacturaCompra)
    factura_venta = models.ForeignKey(FacturaVenta)
    
    def __unicode__(self):
        return u"%s" %(self.fecha)